Skip to main content
Key generation is the foundation of PVAC-HFHE. This guide explains the cryptographic parameters, key structures, and security considerations.

Quick start

Parameters structure

The Params struct controls security and performance trade-offs. From include/pvac/core/types.hpp:36-70:
Default parameters provide 128-bit security (estimated). Security is based on the Learning Parity with Noise (LPN) assumption.

Key parameter meanings

Do not modify default parameters without understanding the security implications. The current settings are tuned for 128-bit security.

Public key structure

From include/pvac/core/types.hpp:123-131:

Key components

Params prm
Copy of the parameter set used for key generation.
uint64_t canon_tag
Random tag for domain separation in PRFs.
std::vector<BitVec> H
LPN matrix H used in encryption.
Fp omega_B
Primitive B-th root of unity in the field.
std::vector<Fp> powg_B
Precomputed powers g^0, g^1, …, g^(B-1) where g generates the multiplicative subgroup of order B.
std::array<uint8_t, 32> H_digest
SHA-256 hash of the matrix H for verification.

Secret key structure

From include/pvac/core/types.hpp:133-136:

Key components

std::array<uint64_t, 4> prf_k
256-bit PRF key (4 × 64-bit words) for generating randomness.
std::vector<uint64_t> lpn_s_bits
LPN secret vector s packed as 64-bit words. Size is (lpn_n + 63) / 64 words.
The secret key must be kept confidential. Anyone with access to sk can decrypt all ciphertexts encrypted under the corresponding pk.

Key generation algorithm

From include/pvac/crypto/keygen.hpp:35-136, the keygen function:
1

Initialize parameters

Copy parameters to public key and verify constraints (e.g., B divides p-1)
2

Generate PRF key

Sample 4 random 64-bit values for sk.prf_k
3

Find generator g

Find a generator of the multiplicative subgroup of order B using exponentiation by (p-1)/B
4

Precompute powers

Compute powg_B[i] = g^i for i = 0 to B-1
5

Find root of unity

Find primitive B-th root of unity ω_B by testing candidates
6

Generate LPN secret

Sample random bits for lpn_s_bits with proper masking
7

Generate matrix H

Create the LPN matrix H (implicit in gen_H)

Generator finding (excerpt)

From include/pvac/crypto/keygen.hpp:67-88:

LPN secret generation (excerpt)

From include/pvac/crypto/keygen.hpp:124-135:

Inspecting generated keys

From examples/basic_usage.cpp:51-56:

Key sizes

Based on benchmark data:
The public key is relatively large (8 MB) but only needs to be generated once per session. The secret key is compact.

Security considerations

LPN hardness

Security is based on the decisional LPN problem:
Security estimates (from include/pvac/core/types.hpp:53-56):
  • Information-theoretic bound: 2226 bits
  • Classical security: 200+ bits
  • Quantum security: 100+ bits
These estimates assume τ = 1/8 (12.5% error rate) with the default parameters.

Performance

From benchmark data (benchmarks/README.md:198):
  • Key generation time: 858.95 ms (mean)
  • Comparison: 22x slower than BFV (38ms), but this is a one-time cost
Key generation is currently unoptimized in this proof-of-concept implementation. Production versions would be significantly faster.

Next steps

Encryption and decryption

Learn how to use the generated keys

Performance tuning

Optimize key generation and usage